package com.sychip.fhc.app.data.repo.impl


import com.sychip.fhc.app.data.repo.WsnDeviceRssiRepo
import com.sychip.fhc.app.data.source.convert.toDto
import com.sychip.fhc.app.data.source.convert.toEntity
import com.sychip.fhc.app.data.source.dao.WsnDeviceRssiDao
import com.sychip.fhc.app.data.source.dto.WsnDeviceRssiDto
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton


@Singleton
class WsnDeviceRssiRepoImpl @Inject constructor(
    private val rssiDao: WsnDeviceRssiDao,
) : WsnDeviceRssiRepo {

    override fun observeLastRssi(usbId: String): Flow<List<WsnDeviceRssiDto>> {
        return rssiDao.observeLastRssi(usbId).map { it.toDto() }
    }
    override fun observeOldestDataFrom(usbId: String, dateTime: Long): Flow<List<WsnDeviceRssiDto>> {
        return rssiDao.observeOldestDataFrom(usbId, dateTime).map { it.toDto() }
    }
    override fun observeAllDataFrom(usbId: String, dateTime: Long): Flow<List<WsnDeviceRssiDto>> {
        return rssiDao.observeAllDataFrom(usbId, dateTime).map { it.toDto() }
    }

    override fun observeRssiByFromToDev(usbId: String, fromDevId: String,toDevId: String): Flow<List<WsnDeviceRssiDto>> {
        Timber.i("######observeRssiByFromToDev######    %s     %s", fromDevId, toDevId)


        return rssiDao.observeRssiByFromToDev(usbId, fromDevId, toDevId).map {
            it.toDto()
        }.catch {e->

            Timber.i("######observeRssiByFromToDev######    %s     ", e.toString())
        }
    }
    override suspend fun addRssiData(usbId: String, fromDevId: String, toDevId: String, rssi: String, dateTime: Long):WsnDeviceRssiDto {
        val task = WsnDeviceRssiDto(
            fromDevId = fromDevId,
            toDevId = toDevId,
            rssi = rssi.toInt(),
            dateTime = dateTime,
        )
        rssiDao.upsert(task.toEntity())
        return task
    }

    override suspend fun getAllData(usbId: String): List<WsnDeviceRssiDto> {
        val devList: List<WsnDeviceRssiDto> =rssiDao.getAll(usbId).toDto()
        return devList

    }
    override suspend fun getAllLastRssi(usbId: String): List<WsnDeviceRssiDto> {
        val devList: List<WsnDeviceRssiDto> =rssiDao.getAllLastRssi(usbId).toDto()
        return devList

    }


    override suspend fun getByFromToAndTime(usbId: String, fromDevId: String,toDevId: String, dateTime: Long)  :List<WsnDeviceRssiDto> {
        val devList:List<WsnDeviceRssiDto> = rssiDao.getByFromToAndTime(usbId, fromDevId, toDevId, dateTime).toDto()
        return devList

    }

    override fun getAllFromDevDataStream(usbId: String, fromDevId: String): Flow<List<WsnDeviceRssiDto>> {
        TODO("Not yet implemented")
    }

    override fun getAllToDevData(usbId: String, toDevId: String): Flow<List<WsnDeviceRssiDto>> = flow {
        val devList:List<WsnDeviceRssiDto> = emptyList()
        rssiDao.getByToDevId(usbId, toDevId).toDto()
        emit(devList)

    }



    override suspend fun deleteAllData(usbId: String) : Int{
        return rssiDao.deleteAll(usbId)
    }

    override suspend fun deleteDeviceAllData(usbId: String, devId: String): Int {
        return rssiDao.deleteByFromId(usbId, devId) + rssiDao.deleteByToId(usbId, devId)
    }

    override suspend fun deleteDataBefore(hours: Int):Int{
        return rssiDao.deleteDataBefore(hours)
    }

}
